package com.ayz.gateway.core.context.context;


import com.ayz.gateway.common.utils.UUIDGenerator;
import com.ayz.gateway.core.authorization.IAuth;
import com.ayz.gateway.core.authorization.service.AuthService;
import com.ayz.gateway.core.context.config.Configuration;
import com.ayz.gateway.core.context.constants.ContextConstants;
import com.ayz.gateway.core.core.Netty.NettyGatewayServer;
import com.ayz.gateway.core.core.Netty.NettyServerConfig;
import com.ayz.gateway.core.datasource.DatasourceFactory;
import com.ayz.gateway.core.session.GatewaySessionFactory;
import com.ayz.gateway.core.session.defaults.DefaultGatewaySessionFactory;
import com.ayz.gateway.core.session.processor.RpcPostProcessorRegistry;
import lombok.Data;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName ApiGatewayContext
 * @Description TODO:网关的上下文
 * @Author 快乐的星球
 * @Date 2023/5/7 11:49
 * @Version 1.0
 **/
@Data
public class ApiGatewayContext implements Context{
    /**
     * 贯穿整个上下文的配置项参数
     * 内存储 RPC泛化调用对象和 各种配置参数
     */
    private Configuration configuration;
    /**
     * 网关的Netty服务
     */
    private NettyGatewayServer nettyServer;
    /**
     * 网关会话工厂类
     */
    private GatewaySessionFactory gatewaySessionFactory;
    /**
     * RPC连接资源数据源工厂
     */
    private DatasourceFactory datasourceFactory;
    /**
     * 立足于网关上下文的RPC增强器的注册器
     */
    private RpcPostProcessorRegistry postProcessorRegistry;
    /**
     * 每一个网关上下文都有唯一一个鉴权服务类
     */
    private IAuth authService;
    /**
     * 每一个上下文都应该有一个密钥,并且会动态刷新
     */
    private String singingKey;
    /**
     * 单线程的定时任务线程池,用于执行网关上下文中需要执行的定时任务
     */
    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r,"ApiGatewayContextScheduledThread");
        }
    });
    public ApiGatewayContext(Configuration configuration, NettyServerConfig nettyServerConfig, DatasourceFactory datasourceFactory,
                             RpcPostProcessorRegistry postProcessorRegistry){
        this.datasourceFactory=datasourceFactory;
        this.configuration=configuration;
        this.gatewaySessionFactory=new DefaultGatewaySessionFactory(configuration,datasourceFactory,postProcessorRegistry);
        this.postProcessorRegistry=postProcessorRegistry;
        this.singingKey= UUIDGenerator.generate();
        this.authService=new AuthService(singingKey);
        this.nettyServer=new NettyGatewayServer(nettyServerConfig, configuration,this.gatewaySessionFactory,this.authService);
    }
    @Override
    public void start() throws Exception {
        nettyServer.start();
        System.out.println(this.singingKey);
        /**
         * TODO: 添加网关上下文中需要执行的一些定时任务
         */
        //1: 添加网关上下文鉴权模块的私钥的刷新时间 默认每隔7天刷新一次
        scheduledExecutorService.scheduleAtFixedRate(()->{
            this.authService.setSingingKey(UUIDGenerator.generate());
        }, ContextConstants.SINGING_KEY_REFRESH_DAYS,ContextConstants.SINGING_KEY_REFRESH_DAYS, TimeUnit.DAYS);
    }
    @Override
    public void shutdown() {
        nettyServer.shutdown();
        this.scheduledExecutorService.shutdown();
    }
}
